Skip to content

[FIX] Fix particle emission rate when looping#8263

Merged
willeastcott merged 2 commits intomainfrom
particle-fix
Dec 19, 2025
Merged

[FIX] Fix particle emission rate when looping#8263
willeastcott merged 2 commits intomainfrom
particle-fix

Conversation

@willeastcott
Copy link
Contributor

@willeastcott willeastcott commented Dec 19, 2025

Fixes an off-by-one error in the particle respawn calculation that caused incorrect emission timing when particles loop.

When a particle's life exceeds its lifetime, the system "rewinds" the particle by subtracting a value to simulate the wait until its next emission slot. The formula was:

max(lifetime, (numParticles - 1) * particleRate)

This is incorrect. With N particles and rate R, the total cycle time should be N * R, not (N - 1) * R.

Example

Configuration: 1 particle, 1s lifetime, 5s emission rate

  • Before: max(1, (1-1) * 5) = 1 → particle respawns immediately after dying
  • After: max(1, 1 * 5) = 5 → particle waits 4 seconds before respawning (correct behavior)

Fixes #4929

Checklist

  • I have read the contributing guidelines
  • My code follows the project's coding standards
  • This PR focuses on a single change

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes an off-by-one error in the particle emission rate calculation that caused incorrect timing when particles loop. The bug affected the formula used to calculate when particles should respawn after their lifetime expires.

Key changes:

  • Changed the particle respawn formula from (numParticles - 1) * particleRate to numParticles * particleRate
  • Updated the formula consistently across both GPU (WGSL and GLSL shaders) and CPU particle system implementations

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/scene/shader-lib/wgsl/chunks/particle/frag/particleUpdaterRespawn.js Fixed respawn calculation for looping particles in WGSL shader
src/scene/shader-lib/wgsl/chunks/particle/frag/particleUpdaterNoRespawn.js Fixed respawn calculation for non-looping particles in WGSL shader
src/scene/shader-lib/wgsl/chunks/particle/frag/particleOutputRgba8.js Fixed max negative life encoding calculation in WGSL output shader
src/scene/shader-lib/wgsl/chunks/particle/frag/particleInputRgba8.js Fixed max negative life decoding calculation in WGSL input shader
src/scene/shader-lib/glsl/chunks/particle/frag/particleUpdaterRespawn.js Fixed respawn calculation for looping particles in GLSL shader
src/scene/shader-lib/glsl/chunks/particle/frag/particleUpdaterNoRespawn.js Fixed respawn calculation for non-looping particles in GLSL shader
src/scene/shader-lib/glsl/chunks/particle/frag/particleOutputRgba8.js Fixed max negative life encoding calculation in GLSL output shader
src/scene/shader-lib/glsl/chunks/particle/frag/particleInputRgba8.js Fixed max negative life decoding calculation in GLSL input shader
src/scene/particle-system/cpu-updater.js Fixed respawn calculation in CPU-based particle updater implementation

The fix is mathematically correct and has been applied consistently across all affected files. With N particles emitted at rate R, the total emission cycle time is indeed N × R, not (N - 1) × R. This ensures proper timing between particle respawns, especially noticeable in the edge case of a single particle with a long emission rate.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@willeastcott willeastcott merged commit 039772a into main Dec 19, 2025
7 checks passed
@willeastcott willeastcott deleted the particle-fix branch December 19, 2025 09:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Particles emission rate is wrong when looping

3 participants